import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;

public class SmithChartPlotterS11 extends JPanel {

    // Your S11 data: frequency (Hz), Re(Γ), Im(Γ)
    private final double[][] points = {
        {100000000,   0.3704,    -0.3274},
        {200000000,   0.16905,   -0.33485},
        {300000000,  -0.0323,    -0.3423},
        {400000000,  -0.12235,   -0.3007},
        {500000000,  -0.2124,    -0.2591},
        {600000000,  -0.23255,   -0.22795},
        {700000000,  -0.2527,    -0.1968},
        {800000000,  -0.27285,   -0.16565},
        {900000000,  -0.2667,    -0.1422},
        {1000000000, -0.2789,    -0.1064},
        {1100000000, -0.2911,    -0.0706},
        {1200000000, -0.3033,    -0.0348},
        {1300000000, -0.3140,     0.0192},
        {1400000000, -0.30695,    0.0824},
        {1500000000, -0.2999,     0.1456},
        {1600000000, -0.29285,    0.2088},
        {1700000000, -0.2837,     0.2948}
    };

    // Convert reflection coefficient Γ to pixel coordinates
    private Point2D gammaToPixel(double re, double im) {
        int centerX = 300;
        int centerY = 300;
        int radius = 250;  // Chart radius in pixels
        double x = centerX + re * radius;
        double y = centerY - im * radius;  // Invert Y for screen coordinates
        return new Point2D.Double(x, y);
    }

    // Draw constant resistance circle (normalized r)
    private void drawResistanceCircle(Graphics2D g, double r) {
        if (r == 0) {  // Short circuit: vertical line at Re= -1
            g.draw(new Line2D.Double(50, 50, 50, 550));
            return;
        }
        double centerX = 300 + 250 * (r / (r + 1));
        double radius = 250 * (1 / (r + 1));
        Ellipse2D circle = new Ellipse2D.Double(centerX - radius, 300 - radius, 2 * radius, 2 * radius);
        g.draw(circle);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // Background
        setBackground(Color.WHITE);

        int width = getWidth();
        int height = getHeight();
        int centerX = width / 2;
        int centerY = height / 2;
        int chartRadius = Math.min(width, height) / 2 - 50;

        // Update conversion to use dynamic size (but keep fixed for simplicity)
        // For now, hardcode to fit 600x600 window
        centerX = 300;
        centerY = 300;
        chartRadius = 250;

        // Draw outer circle (|Γ| = 1)
        g2.setColor(Color.BLACK);
        g2.draw(new Ellipse2D.Double(centerX - chartRadius, centerY - chartRadius,
                                     2 * chartRadius, 2 * chartRadius));

        // Horizontal real axis
        g2.draw(new Line2D.Double(centerX - chartRadius, centerY,
                                  centerX + chartRadius, centerY));

        // Draw some constant resistance circles
        double[] resistances = {0.2, 0.5, 1.0, 2.0, 5.0};
        for (double r : resistances) {
            drawResistanceCircle(g2, r);
        }

        // Plot the points
        g2.setColor(Color.RED);
        g2.setStroke(new BasicStroke(3));

        Point2D prev = null;
        for (int i = 0; i < points.length; i++) {
            double re = points[i][1];
            double im = points[i][2];
            Point2D p = gammaToPixel(re, im);

            // Draw point
            g2.fill(new Ellipse2D.Double(p.getX() - 6, p.getY() - 6, 12, 12));

            // Label with frequency (in MHz)
            long freqMHz = Math.round(points[i][0] / 1e6);
            g2.drawString(freqMHz + " MHz", (float)p.getX() + 10, (float)p.getY() - 10);

            // Connect with line
            if (prev != null) {
                g2.draw(new Line2D.Double(prev, p));
            }
            prev = p;
        }

        // Title
        g2.setColor(Color.BLACK);
        g2.setFont(new Font("SansSerif", Font.BOLD, 20));
        g2.drawString("Smith Chart - 2N3478 S11", 150, 40);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("Smith Chart Plotter");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new SmithChartPlotterS11());
        frame.setSize(600, 650);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}